package com.corn.juc.valatile;

/**
 * @author : Jim Wu
 * @version 1.0
 * @function :
 * @since : 2020/12/17 17:54
 */

public class SingletonVolatileApp {

    // 最严谨的做法加上volatile 禁止指令重排
    private static volatile SingletonVolatileApp INSTANCE = null;

    private SingletonVolatileApp() {

    }

    public static final SingletonVolatileApp getInstance() {
        // 第一层检查 如果 不为空直接返回 屏蔽多数的线程
        if (INSTANCE == null) {
            // 加锁 防止多线程同时进入上层检查 第二层检查使用synchronized加锁操作保证线程安全
            // 不加volatile关键字的话有可能会出现尚未完全初始化就获取到的情况。原因是内存模型允许无序写入
            synchronized (SingletonVolatileApp.class) {
                if (INSTANCE == null) {
                    INSTANCE = new SingletonVolatileApp();
                }
            }
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 50; i++) {
            new Thread() {
                @Override
                public void run() {
                    System.out.println(SingletonVolatileApp.getInstance());
                }
            }.start();
        }
        while (Thread.activeCount() > 2) {
            Thread.yield();
        }
    }
}
